<template>
  <view class="container" :style="{ height: editorHeight + 'rpx' }">
    <view class="wrapper">
      <view class="toolbar" @tap="format" style="width: 100%" :style="{ height: toolbarHeight + 'rpx' }">
        <view
          v-if="is_hidden_icon('bold')"
          :style="iconStyle"
          :class="formats.bold ? 'ql-active' : ''"
          class="iconfont icon-zitijiacu"
          data-name="bold"
        ></view>
        <view
          v-if="is_hidden_icon('italic')"
          :style="iconStyle"
          :class="formats.italic ? 'ql-active' : ''"
          class="iconfont icon-zitixieti"
          data-name="italic"
        ></view>
        <view
          v-if="is_hidden_icon('underline')"
          :style="iconStyle"
          :class="formats.underline ? 'ql-active' : ''"
          class="iconfont icon-zitixiahuaxian"
          data-name="underline"
        ></view>
        <view
          v-if="is_hidden_icon('strike')"
          :class="formats.strike ? 'ql-active' : ''"
          :style="iconStyle"
          class="iconfont icon-zitishanchuxian"
          data-name="strike"
        ></view>
        <view
          v-if="is_hidden_icon('left')"
          :style="iconStyle"
          :class="formats.align === 'left' ? 'ql-active' : ''"
          class="iconfont icon-zuoduiqi"
          data-name="align"
          data-value="left"
        ></view>
        <view
          v-if="is_hidden_icon('center')"
          :style="iconStyle"
          :class="formats.align === 'center' ? 'ql-active' : ''"
          class="iconfont icon-juzhongduiqi"
          data-name="align"
          data-value="center"
        ></view>
        <view
          v-if="is_hidden_icon('right')"
          :style="iconStyle"
          :class="formats.align === 'right' ? 'ql-active' : ''"
          class="iconfont icon-youduiqi"
          data-name="align"
          data-value="right"
        ></view>
        <view
          v-if="is_hidden_icon('justify')"
          :style="iconStyle"
          :class="formats.align === 'justify' ? 'ql-active' : ''"
          class="iconfont icon-zuoyouduiqi"
          data-name="align"
          data-value="justify"
        ></view>
        <view
          v-if="is_hidden_icon('lineHeight')"
          :style="iconStyle"
          :class="formats.lineHeight ? 'ql-active' : ''"
          class="iconfont icon-line-height"
          data-name="lineHeight"
          data-value="2"
        ></view>
        <view
          v-if="is_hidden_icon('letterSpacing')"
          :style="iconStyle"
          :class="formats.letterSpacing ? 'ql-active' : ''"
          class="iconfont icon-Character-Spacing"
          data-name="letterSpacing"
          data-value="2em"
        ></view>
        <view
          v-if="is_hidden_icon('marginTop')"
          :style="iconStyle"
          :class="formats.marginTop ? 'ql-active' : ''"
          class="iconfont icon-722bianjiqi_duanqianju"
          data-name="marginTop"
          data-value="20px"
        ></view>
        <view
          v-if="is_hidden_icon('marginBottom')"
          :style="iconStyle"
          :class="formats.marginBottom ? 'ql-active' : ''"
          class="iconfont icon-723bianjiqi_duanhouju"
          data-name="marginBottom"
          data-value="20px"
        ></view>
        <view v-if="is_hidden_icon('clearedformat')" :style="iconStyle" class="iconfont icon-clearedformat" @tap="removeFormat"></view>
        <view
          v-if="is_hidden_icon('fontFamily')"
          :style="iconStyle"
          :class="formats.fontFamily ? 'ql-active' : ''"
          class="iconfont icon-font"
          data-name="fontFamily"
          data-value="Pacifico"
        ></view>
        <view
          v-if="is_hidden_icon('fontSize')"
          :style="iconStyle"
          :class="formats.fontSize === '24px' ? 'ql-active' : ''"
          class="iconfont icon-fontsize"
          data-name="fontSize"
          data-value="24px"
        ></view>

        <view
          v-if="is_hidden_icon('color')"
          :style="iconStyle"
          :class="formats.color === '#0000ff' ? 'ql-active' : ''"
          class="iconfont icon-text_color"
          data-name="color"
          data-value="#0000ff"
        ></view>
        <view
          v-if="is_hidden_icon('backgroundColor')"
          :style="iconStyle"
          :class="formats.backgroundColor === '#00ff00' ? 'ql-active' : ''"
          class="iconfont icon-fontbgcolor"
          data-name="backgroundColor"
          data-value="#00ff00"
        ></view>

        <view v-if="is_hidden_icon('date')" :style="iconStyle" class="iconfont icon-date" @tap="insertDate"></view>
        <view v-if="is_hidden_icon('list')" :style="iconStyle" class="iconfont icon--checklist" data-name="list" data-value="check"></view>
        <view
          v-if="is_hidden_icon('ordered')"
          :style="iconStyle"
          :class="formats.list === 'ordered' ? 'ql-active' : ''"
          class="iconfont icon-youxupailie"
          data-name="list"
          data-value="ordered"
        ></view>
        <view
          v-if="is_hidden_icon('bullet')"
          :style="iconStyle"
          :class="formats.list === 'bullet' ? 'ql-active' : ''"
          class="iconfont icon-wuxupailie"
          data-name="list"
          data-value="bullet"
        ></view>
        <view v-if="is_hidden_icon('undo')" :style="iconStyle" class="iconfont icon-undo" @tap="undo"></view>
        <view v-if="is_hidden_icon('redo')" :style="iconStyle" class="iconfont icon-redo" @tap="redo"></view>
        <view v-if="is_hidden_icon('outdent')" :style="iconStyle" class="iconfont icon-outdent" data-name="indent" data-value="-1"></view>
        <view v-if="is_hidden_icon('indent')" :style="iconStyle" class="iconfont icon-indent" data-name="indent" data-value="+1"></view>
        <view v-if="is_hidden_icon('divider')" :style="iconStyle" class="iconfont icon-fengexian" @tap="insertDivider"></view>
        <view v-if="is_hidden_icon('image')" :style="iconStyle" class="iconfont icon-charutupian" @tap="chooseInsertImage"></view>
        <view
          v-if="is_hidden_icon('header')"
          :style="iconStyle"
          :class="formats.header === 1 ? 'ql-active' : ''"
          class="iconfont icon-format-header-1"
          data-name="header"
          :data-value="1"
        ></view>
        <view
          v-if="is_hidden_icon('sub')"
          :style="iconStyle"
          :class="formats.script === 'sub' ? 'ql-active' : ''"
          class="iconfont icon-zitixiabiao"
          data-name="script"
          data-value="sub"
        ></view>
        <view
          v-if="is_hidden_icon('super')"
          :style="iconStyle"
          :class="formats.script === 'super' ? 'ql-active' : ''"
          class="iconfont icon-zitishangbiao"
          data-name="script"
          data-value="super"
        ></view>
        <view v-if="is_hidden_icon('clear')" :style="iconStyle" class="iconfont icon-shanchu" @tap="clear"></view>
        <view
          v-if="is_hidden_icon('direction')"
          :style="iconStyle"
          :class="formats.direction === 'rtl' ? 'ql-active' : ''"
          class="iconfont icon-direction-rtl"
          data-name="direction"
          data-value="rtl"
        ></view>
      </view>
      <view class="editor-wrapper" :style="editorStyle">
        <editor
          :id="'editor' + editorName"
          class="ql-container"
          :placeholder="placeholder"
          showImgSize
          showImgToolbar
          showImgResize
          @input="editorChange"
          @statuschange="onStatusChange"
          :read-only="readOnly"
          @ready="onEditorReady"
        ></editor>
      </view>
    </view>
  </view>
</template>

<script>
import { getUUID } from '@/common/utils/utils.js'
import { syncUniApi } from '@/common/utils/utils.js'
import UploadImage from '@/common/utils/upload-image.js'
export default {
  name: 'benben-editor',
  props: {
    editorHeight: {
      type: [Number, String],
      default: 600,
    },
    fontSize: {
      type: [Number, String],
      default: 32,
    },
    IconHeight: {
      type: [Number, String],
      default: 48,
    },
    value: {
      type: [String],
      default: '',
    },
    hiddenIcons: {
      type: [Array],
      default: () => [],
    },
    placeholder: {
      type: [String],
      default: '',
    },
    readOnly: {
      type: [Boolean],
      default: false,
    },
  },
  data() {
    return {
      formats: {},
      editorCtx: '',
      toolbar_icon_all_num: 32,
      editorName: getUUID(),
    }
  },
  watch: {
    value: {
      handler(val) {
        if (this.isupdata) {
          this.isupdata = false
          return
        }
        if (this.editorCtx) {
          this.editorCtx.setContents({
            html: val,
          })
        }
      },
      immediate: true,
    },
  },
  computed: {
    iconStyle() {
      let height = this.IconHeight + 'rpx'
      let fontSize = this.fontSize + 'rpx'
      return {
        height,
        lineHeight: height,
        fontSize,
      }
    },
    toolbarHeight() {
      return Math.ceil((this.toolbar_icon_all_num - this.hiddenIcons.length) / 9) * this.IconHeight
    },
    editorStyle() {
      let height = this.editorHeight - this.toolbarHeight
      return {
        height: height + 'rpx',
      }
    },
  },
  methods: {
    is_hidden_icon(ident) {
      let list = this.hiddenIcons || []
      if (list.length < 1) return true
      return list.findIndex((item) => item == ident) == -1
    },
    editorChange(e) {
      this.isupdata = true
      this.$emit('input', e.detail.html)
      this.$emit('change', e.detail.html)
    },
    onEditorReady() {
      const { value, editorName } = this
      uni
        .createSelectorQuery()
        .select(`#editor${editorName}`)
        .context((res) => {
          this.editorCtx = res.context
          this.editorCtx.setContents({
            html: !value ? '' : value,
          })
        })
        .exec()
    },
    setHtml(html) {
      if (this.editorCtx) {
        this.editorCtx.setContents({
          html: html,
        })
      } else {
        this.$nextTick(() => {
          uni
            .createSelectorQuery()
            .in(this)
            .select(`#editor${this.editorName}`)
            .context((res) => {
              this.editorCtx = res.context
              this.editorCtx.setContents({
                html: html,
              })
            })
            .exec()
        })
      }
    },
    getContent() {
      return new Promise((reslove, reject) => {
        this.editorCtx.getContents({
          success: function (res) {
            reslove(res)
          },
          fail: function (err) {
            reject(err)
          },
        })
      })
    },
    undo() {
      this.editorCtx.undo()
    },
    redo() {
      this.editorCtx.redo()
    },
    format(e) {
      let { name, value } = e.target.dataset
      if (!name) return
      // console.log('format', name, value)
      this.editorCtx.format(name, value)
    },
    onStatusChange(e) {
      const formats = e.detail
      this.formats = formats
    },
    insertDivider() {
      this.editorCtx.insertDivider({
        success: function () {
          console.log('insert divider success')
        },
      })
    },
    clear() {
      uni.showModal({
        title: '清空编辑器',
        content: '确定清空编辑器全部内容？',
        success: (res) => {
          if (res.confirm) {
            this.editorCtx.clear({
              success: function (res) {
                console.log('clear success')
              },
            })
          }
        },
      })
    },
    removeFormat() {
      this.editorCtx.removeFormat()
    },
    insertDate() {
      const date = new Date()
      const formatDate = `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`
      this.editorCtx.insertText({
        text: formatDate,
      })
    },
    insertImage(image) {
        this.editorCtx.insertImage({
          src: image,
          alt: '图像',
          success: () => {
            console.log('insert image success')
            this.insertImageTest = true
          },
        })
    },
    async chooseInsertImage() {
      let FilesRes = await syncUniApi('chooseImage', {
        count: 1,
        sourceType: ['album', 'camera'],
        sizeType: ['original', 'compressed'],
      })
      new UploadImage(FilesRes.tempFiles, {
        complete: (res) => {
          this.insertImage(res[0].path)
        },
      })
    },
  },
  onLoad() {
    uni.loadFontFace({
      family: 'Pacifico',
      source: 'url("https://sungd.github.io/Pacifico.ttf")',
    })
  },
}
</script>

<style lang="scss" scoped>
@import './editor-icon.css';

.container {
  width: 100%;
}

.wrapper {
  width: 100%;
  height: 100%;
  display: flex;
  flex-wrap: wrap;
}

.editor-wrapper {
  width: 100%;
  background: #fff;
}

.iconfont {
  display: inline-block;
  text-align: center;
  width: calc(100% / 9);
  cursor: pointer;
  color: #666;
}

.toolbar {
  box-sizing: border-box;
  border-bottom: 0;
  font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  // background: rgba(0,0,0,0.1);
  border-radius: 6rpx;
}

.toolbar::after {
  content: '';
  flex: auto;
}

.ql-container {
  box-sizing: border-box;
  padding: 12rpx 0rpx;
  width: 100%;
  // min-height: 30vh;
  height: 100%;
  /* margin-top: 20px; */
  font-size: 32rpx;
  line-height: 1.5;
}

.ql-active {
  color: #06c;
}

::v-deep .ql-editor.ql-blank:before {
  font-style: normal !important;
}

::v-deep .ql-container {
  min-height: 0;
}
</style>
